package com.drason.encapsulation.loadmore;

import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

import com.drason.encapsulation.R;


/**
 * Created by drason on 2017/11/6.
 */

public class MyLoadMoreRecyclerView extends RecyclerView {
    //recyclerview 状态
    enum State {
        LOADING, COMPLETE, END
    }


    //设置当前加载状态
    private static State mLoadState = State.COMPLETE;
    private OnLoadMoreListener loadMoreListener;//加载数据监听
    private MyAdapter mMyAdapter;
    private static int footerLayoutRes = 0;
    private static int endLayoutRes = 0;

    public MyLoadMoreRecyclerView(Context context) {
        this(context, null);
    }

    public MyLoadMoreRecyclerView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyLoadMoreRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        // 滑动时判断状态改变
        setOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                //滑动时, 什么时候正常, 什么时候显示加载更多, 什么时候显示全部加载完成!
                if (getAdapter() != null && getLayoutManager() != null) {
                    LayoutManager layoutManager = getLayoutManager();
                    int lastVisiblePosition;
                    if (layoutManager instanceof GridLayoutManager) {
                        lastVisiblePosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
                    } else if (layoutManager instanceof LinearLayoutManager) {
                        lastVisiblePosition = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition();
                    } else {
                        int[] positions = ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(null);
                        lastVisiblePosition = findMax(positions);
                    }

                    int itemCount = getAdapter().getItemCount();
                    if (lastVisiblePosition < itemCount - 1) return;
                    if (distanceY < 0 && itemCount != 0 && mLoadState == State.COMPLETE) {
                        mLoadState = State.LOADING;
                        getAdapter().notifyItemChanged(itemCount - 1);
                        if (loadMoreListener != null) {
                            loadMoreListener.loadMoreListener();
                        }
                    }
                }
            }
        });
    }

    public void notifyData() {
        if (getAdapter() != null) {
            mLoadState = State.COMPLETE;
        }
        getAdapter().notifyDataSetChanged();
    }

    public void setHasMore(boolean hasMore) {
        mLoadState = hasMore ? State.COMPLETE : State.END;
        getAdapter().notifyDataSetChanged();
    }

    public void setFooterLayoutRes(int layoutRes) {
        this.footerLayoutRes = layoutRes;
    }

    public void setEndLayoutRes(int layoutRes) {
        this.endLayoutRes = layoutRes;
    }


    @Override
    public void setAdapter(Adapter adapter) {
        mMyAdapter = new MyAdapter(adapter);
        super.setAdapter(mMyAdapter);
    }

    private int findMax(int[] array) {
        int value = Integer.MIN_VALUE;
        for (int i = 0; i < array.length; i++) {
            if (array[i] > value) {
                value = array[i];
            }
        }
        return value;
    }

    /**
     * 判断滑动方向
     */
    private float distanceY = 0;
    float startY = 0;

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        float y = ev.getRawY();
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                distanceY = y - startY;
                startY = y;
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

    /**
     * 加载更多数据回调
     *
     * @param listener
     */
    public void setOnLoadMoreListener(MyLoadMoreRecyclerView.OnLoadMoreListener listener) {
        this.loadMoreListener = listener;
    }

    public interface OnLoadMoreListener {
        void loadMoreListener();//上拉刷新
    }

    public static class MyAdapter extends Adapter<ViewHolder> {

        enum ItemType {
            FOOTER(1), NORMAL(2);

            ItemType(int type) {
                this.type = type;
            }

            private int type = 2;

            public int getType() {
                return type;
            }

        }

        private Adapter dataAdapter;

        public MyAdapter(Adapter dataAdapter) {
            this.dataAdapter = dataAdapter;
        }


        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            if (viewType == ItemType.FOOTER.getType()) {
                View footerItemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.viewholder_footer, parent, false);
                setFooterAndEnd(parent, footerItemView);
                FooterVH footerVH = new FooterVH(footerItemView);
                return footerVH;
            } else {
                return dataAdapter.onCreateViewHolder(parent, viewType);
            }
        }

        private void setFooterAndEnd(ViewGroup parent, View footerItemView) {
            RelativeLayout footerContainer = (RelativeLayout) footerItemView.findViewById(R.id.rl_footer);
            RelativeLayout endContainer = (RelativeLayout) footerItemView.findViewById(R.id.rl_end);
            if (footerLayoutRes != 0) {
                View footView = LayoutInflater.from(parent.getContext()).inflate(footerLayoutRes, null);
                footerContainer.removeAllViews();
                footerContainer.addView(footView);
            }

            if (endLayoutRes != 0) {
                View endView = LayoutInflater.from(parent.getContext()).inflate(endLayoutRes, null);
                endContainer.removeAllViews();
                endContainer.addView(endView);
            }
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            if (holder instanceof FooterVH) {
                FooterVH footerVH = (FooterVH) holder;
                bindFooterData(footerVH);
            } else {
                dataAdapter.onBindViewHolder(holder, position);
            }

        }

        private void bindFooterData(FooterVH footerVH) {
            switch (mLoadState) {
                case LOADING:
                    footerVH.mRlFooter.setVisibility(VISIBLE);
                    footerVH.mRlEnd.setVisibility(GONE);
                    break;
                case COMPLETE:
                    footerVH.mRlFooter.setVisibility(INVISIBLE);
                    footerVH.mRlEnd.setVisibility(GONE);
                    break;
                case END:
                    footerVH.mRlFooter.setVisibility(GONE);
                    footerVH.mRlEnd.setVisibility(VISIBLE);
                    break;
            }
        }

        @Override
        public int getItemCount() {
            if (dataAdapter.getItemCount() != 0) {
                return dataAdapter.getItemCount() + 1;
            }
            return 0;
        }

        @Override
        public int getItemViewType(int position) {
            int itemCount = dataAdapter.getItemCount();
            if (itemCount <= 0) return super.getItemViewType(position);
            if (position == getItemCount() - 1) {
                return ItemType.FOOTER.getType();
            } else {
                return ItemType.NORMAL.getType();
            }
        }

        // 以下为footer 设置一行
        @Override
        public void onAttachedToRecyclerView(RecyclerView recyclerView) {
            super.onAttachedToRecyclerView(recyclerView);
            LayoutManager layoutManager = recyclerView.getLayoutManager();
            if (layoutManager instanceof GridLayoutManager) {
                final GridLayoutManager manager = (GridLayoutManager) layoutManager;
                manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                    @Override
                    public int getSpanSize(int position) {
                        return getItemViewType(position) == ItemType.FOOTER.getType() ?
                                manager.getSpanCount() : 1;
                    }
                });
            }
        }

        @Override
        public void onViewAttachedToWindow(ViewHolder holder) {
            super.onViewAttachedToWindow(holder);
            ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
            if (holder instanceof FooterVH && layoutParams != null
                    && layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) {
                StaggeredGridLayoutManager.LayoutParams lp =
                        (StaggeredGridLayoutManager.LayoutParams) layoutParams;
                lp.setFullSpan(true);
                holder.itemView.setLayoutParams(lp);
            }
        }
    }
}
